#include "String.h"

//strlen
size_t strlen(const char* str)
{
	assert(str);
	int num = 0;
	while (*str != '\0')
	{
		num++;
		str++;
	}
	return num;
}

//strcpy
char* strcpy(char* destination, const char* source)
{
	assert(destination&&source);

	char* tmp = destination;

	while (*tmp++ = *source++)
	{
		;
	}
	*tmp = '\0';

	return destination;
}

//strcat
char* strcat(char* destination, const char* source)
{
	assert(destination&&source);
	char* tmp= destination;
	while (*tmp!='\0')
	{
		tmp++;
	}
	strcpy(tmp, source);
	return destination;
}

//strcmp
int strcmp(const char * str1, const char * str2)
{
	assert(str1&&str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return (*str1 - *str2);
}

//strncpy
char * strncpy(char * destination, const char * source, size_t num)
{
	assert(destination&&source);
	char* tmp = destination;

	while (*source&&num>0)
	{
		*tmp++ = *source++;
		num--;
	}
	while (num>0)
	{
		*tmp++ = '\0';
		num--;
	}

	return destination;
}

//strncat
char * strncat(char * destination, const char * source, size_t num)
{
	assert(destination&&source);
	char* tmp = destination;
	while (*tmp != '\0')
	{
		tmp++;
	}
	while (*source&&num>0)
	{
		*tmp++ = *source++;
		num--;
	}
	*tmp = '\0';
	return destination;
}

//strncmp
int strncmp(const char * str1, const char * str2, size_t num)
{
	assert(str1&&str2);
	while ((*str1 == *str2)&&num>0)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
		num--;
	}
	if (num == 0)
		return 0;
	return (*str1 - *str2);
}


//strstr
char* strstr(const char *str1, const char * str2)
{
	assert(str1&&str2);
	// �������ַ������������
	if (*str2 == '\0') {
		return (char*)str1;  // ���ַ���ƥ�������ַ���
	}
	const char* ps1 = str1;
	
	while (*ps1 != '\0')
	{
		const char* begin = ps1;
		const char* ps2 = str2;

		while (*ps1 != '\0' && *ps2 != '\0' && *ps1 == *ps2)
		{
			ps1++;
			ps2++;
		}
		if (*ps2 == '\0')
			return (char*)begin;

		ps1 = begin+1;

	}
	if (*ps1 == '\0')
		return NULL;
}


//strtok
char * strtok(char* str, const char * sep) {
    static char* last = NULL; // 静态变量保存上次处理的位置
    
    // 首次调用或显式传入NULL继续处理
    if (str != NULL) {
        last = str;
    } else if (last == NULL) {
        return NULL; // 没有更多标记
    }
    
    // 跳过前导分隔符
    while (*last != '\0' && strchr(sep, *last) != NULL) {
        last++;
    }
    
    if (*last == '\0') {
        last = NULL; // 没有更多标记
        return NULL;
    }
    
    // 找到当前标记的结束位置
    char* token = last;
    while (*last != '\0' && strchr(sep, *last) == NULL) {
        last++;
    }
    
    if (*last != '\0') {
        *last = '\0'; // 替换分隔符为字符串结束符
        last++;       // 移动到下一个位置
    } else {
        last = NULL;  // 处理完毕，下次调用返回NULL
    }
    
    return token;
}

//strerror
char * strerror(int errnum) {
    // 错误信息数组（实际实现可能更大）
    static const char* const error_messages[] = {
        [0] = "No error",
        [1] = "Operation not permitted",
        [2] = "No such file or directory",
        [3] = "No such process",
        [4] = "Interrupted system call",
        [5] = "Input/output error",
        [6] = "Device not configured",
        [7] = "Argument list too long",
        [8] = "Exec format error",
        [9] = "Bad file descriptor",
        [10] = "No child processes",
        // 更多错误码...
    };
    
    // 静态缓冲区用于返回错误信息
    static char unknown_error[32];
    
    // 检查错误码是否在预定义范围内
    size_t max_errors = sizeof(error_messages) / sizeof(error_messages[0]);
    if (errnum >= 0 && (size_t)errnum < max_errors && error_messages[errnum] != NULL) {
        return (char*)error_messages[errnum];
    }
    
    // 处理未知错误码
    snprintf(unknown_error, sizeof(unknown_error), "Unknown error %d", errnum);
    return unknown_error;
}


//memcpy
void * memcpy(void* destination, const void* source, size_t num)
{
	assert(destination != NULL || num == 0);
	assert(source != NULL || num == 0);

	if (destination == source) {
		return destination;
	}
	void *orig_dest = destination;
	while (num--) {
		*(char *)destination = *(char *)source;
		destination = (char *)destination + 1;
		source = (char *)source + 1;
	}
	return orig_dest;
}

//memmove
void * memmove(void * destination, const void * source, size_t num)
{
	assert(destination != NULL || num == 0);
	assert(source != NULL || num == 0);
	void *orig_dest = destination;
	if (destination < source) 
	{	
		memcpy(destination, source, num);
	}
	else
	{
		// ��ȫ�������
		char *dst = (char *)destination + num - 1;
		const char *src = (const char *)source + num - 1;
		while (num--) {
			*(char *)dst = *(char *)src;
			dst = (char *)dst - 1;
			src = (char *)src - 1;
		}
	}
	
	return orig_dest;
}

//memcmp
int memcmp(const void * ptr1, const void * ptr2, size_t num)
{
	assert(ptr1 && ptr2);
	const char *p1 = (const char *)ptr1;
	const char *p2 = (const char *)ptr2;

	while (num-- > 0) 
	{
		if (*p1 != *p2) 
			return (char)*p1 - (char)*p2;
		p1++;
		p2++;
	}
	return 0;  
}

//memset
void * memset(void * ptr, int value, size_t num)
{
	assert(ptr);
	void *orig_ptr = ptr;
	while (num--)
	{
		*(char*)ptr = (char)value;
		ptr = (char*)ptr + 1;
	}
	return orig_ptr;
}
